package main

import (
	"flag"
	"fmt"
	"net/http"
	_ "net/http/pprof"
	"os"
	"os/signal"
	"syscall"

	"gitee.com/kennyzw/go-sip-ua/pkg/utils"
	"gitee.com/kennyzw/gosip/log"
	"github.com/c-bata/go-prompt"
)

func completer(d prompt.Document) []prompt.Suggest {
	s := []prompt.Suggest{
		{Text: "users", Description: "Show sip accounts"},
		{Text: "onlines", Description: "Show online sip devices"},
		{Text: "calls", Description: "Show active calls"},
		{Text: "set debug on", Description: "Show debug msg in console"},
		{Text: "set debug off", Description: "Turn off debug msg in console"},
		{Text: "show loggers", Description: "Print Loggers"},
		{Text: "exit", Description: "Exit"},
	}
	return prompt.FilterHasPrefix(s, d.GetWordBeforeCursor(), true)
}

func usage() {
	fmt.Fprintf(os.Stderr, `go pbx version: go-pbx/1.10.0
Usage: server [-nc]

Options:
`)
	flag.PrintDefaults()
}

// 控制面板交互.
func consoleLoop(hijackUa *HijackUA) {
	fmt.Println("Please select command.")
	for {
		t := prompt.Input("CLI> ", completer,
			prompt.OptionTitle("GO B2BUA 1.0.0"),
			prompt.OptionHistory([]string{"calls", "users", "onlines"}),
			prompt.OptionPrefixTextColor(prompt.Yellow),
			prompt.OptionPreviewSuggestionTextColor(prompt.Blue),
			prompt.OptionSelectedSuggestionBGColor(prompt.LightGray),
			prompt.OptionSuggestionBGColor(prompt.DarkGray))

		switch t {
		case "show loggers":
			loggers := utils.GetLoggers()
			for prefix, log := range loggers {
				fmt.Printf("%v => %v\n", prefix, log.Level())
			}
		case "set debug on":
			hijackUa.SetLogLevel(log.DebugLevel)
			fmt.Printf("Set Log level to debug\n")
		case "set debug off":
			hijackUa.SetLogLevel(log.ErrorLevel)
			fmt.Printf("Set Log level to info\n")
		case "users":
			fallthrough
		case "ul": /* user list*/
			accounts := hijackUa.GetAccounts()
			if len(accounts) > 0 {
				fmt.Printf("Users:\n")
				fmt.Printf("Username \t Password\n")
				for user, pass := range accounts {
					fmt.Printf("%v \t\t %v\n", user, pass)
				}
			} else {
				fmt.Printf("No users\n")
			}
		case "calls":
			fallthrough
		case "cl": /* call list*/
			calls := hijackUa.Calls()
			if len(calls) > 0 {
				fmt.Printf("Calls:\n")
				for _, call := range calls {
					fmt.Printf("%v:\n", call.ToString())
				}
			} else {
				fmt.Printf("No active calls\n")
			}
		case "exit":
			fmt.Println("Exit now.")
			hijackUa.Shutdown()
			return
		}
	}
}

func main() {
	noconsole := false
	h := false
	host := ""
	d := false

	// ./hijackAs -ip "172.31.35.65" -d 1
	flag.BoolVar(&h, "h", false, "this help")
	flag.BoolVar(&noconsole, "nc", false, "no console mode")
	flag.StringVar(&host, "ip", "10.188.38.134", "host ip") // "10.188.38.134"
	flag.BoolVar(&d, "d", false, "debug open")
	flag.Usage = usage
	flag.Parse()
	if h {
		flag.Usage()
		return
	}

	stop := make(chan os.Signal, 1)
	signal.Notify(stop, syscall.SIGTERM, syscall.SIGINT)

	go func() {
		// 6658 for http.
		fmt.Print("Start pprof on :6658\n")
		http.ListenAndServe(":6658", nil)
	}()

	hiJack := NewHijackUA(host)
	if d {
		hiJack.SetLogLevel(log.DebugLevel)
		fmt.Printf("Set Log level to debug\n")
	} else {
		hiJack.SetLogLevel(log.ErrorLevel)
		fmt.Printf("Set Log level to info\n")
	}

	// Add sample accounts.
	hiJack.AddAccount("100", "100")
	hiJack.AddAccount("200", "200")
	hiJack.AddAccount("300", "300")
	hiJack.AddAccount("400", "400")
	hiJack.AddAccount("500", "500")
	if !noconsole {
		//consoleLoop(hiJack)
		//return
	}

	<-stop
	hiJack.Shutdown()
}
